package com.scyshkj.university.wechat.utils;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.springframework.util.StringUtils;

import java.lang.reflect.Field;
import java.util.*;

/**
 * Created by 唐旭 on 2016/11/22.
 */
public interface ParameterToMap {

    default String toUrlString() {
        Map<String, String> stringMap = toMap();
        return sortParameters(stringMap, "&");
    }

    /**
     * 将对象非空属性转换为map键值对
     *
     * @return 转换后的键值对
     */
    default Map<String, String> toMap() {
        Field[] fields = this.getClass().getDeclaredFields();
        Map<String, String> stringMap = new HashMap<>();
        for (Field field : fields) {
            if (isIgnore(field)) {
                continue;
            }
            String key = getFieldName(field);
            String value = getFieldValue(field);
            if (StringUtils.isEmpty(value)) {
                continue;
            }
            stringMap.put(key, value);
        }
        return stringMap;
    }

    default String getFieldValue(Field field) {
        field.setAccessible(true);
        String value = "";
        try {
            Object o = field.get(this);
            if (!StringUtils.isEmpty(o)) {
                value = o.toString();
            }
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }

        return value;
    }

    default String getFieldName(Field field) {
        JsonProperty annotation = field.getAnnotation(JsonProperty.class);
        if (annotation != null) {
            return annotation.value();
        }

        return field.getName();
    }

    default boolean isIgnore(Field field) {
        JsonIgnore annotation = field.getAnnotation(JsonIgnore.class);
        return annotation != null;
    }

    default String sortParameters(Map<String, String> map, String separator) {
        List<String> list = new ArrayList<>(map.keySet());
        Collections.sort(list);
        StringBuilder builder = new StringBuilder();
        for (String item : list) {
            String value = map.get(item);
            if (!StringUtils.isEmpty(value)) {
                builder.append(String.format("%s=%s" + separator, item, value));
            }
        }
        if (!StringUtils.isEmpty(separator) && builder.length() > 0) {
            builder.deleteCharAt(builder.length() - 1);
        }
        return builder.toString();
    }
}
